﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text;

namespace GACFFP.Controllers
{
    public class PollController : Controller
    {
        //
        // GET: /Poll/
        public ActionResult Index()
        {
            GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();

            IList<RankedTeams>rankedTeams =  gr.GetCurrentPoll();

            string fpVotes = "";
            int counter = 1;

            StringBuilder sbCurrentPoll = new StringBuilder();
            StringBuilder sbCurrentOver = new StringBuilder();

            sbCurrentPoll.Append(@"<div class='ContentHolder'>");

            sbCurrentPoll.Append(@"<table  class='Table' width='100%' border='0' cellpadding='3' cellspacing='1'><tr><td colspan='4' align='center' class='TitleRow'><span class='headerRed' style='color:#ffffff'><b>GACFF POLL</b></span></td></tr><tr class='HeaderRow'><td  ><b>Rank</b></td><td ><b>Team</b></td><td ><b>Points</b></td><td ><b>First Place Votes</b></td</tr>");


            foreach (var rt in rankedTeams)
            {
                if (counter < 26)
                {
                    if (rt.FP > 0)
                    { fpVotes = "[" + rt.FP.ToString() + "]"; }
                    else
                    { fpVotes = ""; }

                    sbCurrentPoll.Append(@"<tr class='RowStyle" + (counter % 2).ToString() + "'>");
                    sbCurrentPoll.Append(@"<td>" + counter.ToString() + ".&nbsp; </td>");
                    sbCurrentPoll.Append(@"<td>" + rt.teamName + "</td>");
                    sbCurrentPoll.Append(@"<td>" + rt.Points.ToString() + "</td>");
                    sbCurrentPoll.Append(@"<td>" + fpVotes + "</td>");
                    sbCurrentPoll.Append(@"</tr>");

                }
                else 
                {
                     sbCurrentOver.Append(@"<span class='xsmalltext'>" + rt.teamName +"("+rt.Points.ToString()+")</span>, ");
                
                }

                if (counter == 40) break;
                counter++;
            }
            sbCurrentPoll.Append(@"</table></br>");
            sbCurrentOver.Append(@"</div>");
            //teams getting points but ranked 26-40
           
            



            ViewData["Poll"] = sbCurrentPoll.ToString()+sbCurrentOver.ToString();

            return View();

        }

        public ActionResult SeeDates()
        {       

            ViewData["StartOfWeek"] = Services.PeriodValidator.GetThisWeekStart();
            ViewData["EndOfWeek"] = Services.PeriodValidator.GetThisWeekEnd();
            ViewData["ValidDay"] = Services.PeriodValidator.IsTodayValid().ToString();

            ViewData["ValidSeason"] = Services.PeriodValidator.IsTodayInSeason().ToString();

            return View();
        
        }

       
        /// <summary>
        /// This AR takes an integer representing the userid and returns the user from the db.  
        /// Currently it will send the name to the viewdata element on the View.
        /// </summary>
        /// <param name="UserId">int</param>
        /// <returns>view</returns>
        public ActionResult UserDetail(int UserId=2)
        {
            GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();


                var thisUser = new GACFFP.User();

                try
                {
                    //get user by passing name into the onion username->userid->user
                    thisUser = gr.GetCurrentUser();
                }
                catch (Exception e)
                {
                    //TODO logging logic


                    ViewData["PageMessage"] += "Problem retrieving user.  :(";
                    return View();
                }


                //show admin control bar
                if (thisUser.role.Trim() == "admin")
                {

                    StringBuilder sbADminControlBar = new StringBuilder();
                    sbADminControlBar.Append(@"<div align='center'><a href='/poll/createuser'>create new user</a> | <a href='/poll/editvotes'>edit votes</a> | <a href='/poll/userdetail'>manage season</a></div>");
                    ViewData["AdminControlBar"] = sbADminControlBar.ToString();
                }



                if (thisUser.id >= 0)
                {
                    StringBuilder sbUserDetail = new StringBuilder();

                    //html output
                    sbUserDetail.Append(@"<div class='formWrapper'>");
                    sbUserDetail.Append(@"<table  class='cellborder' width='100%' border='0' cellpadding='3' cellspacing='1'>");
                    sbUserDetail.Append(@"<tr><td colspan='2' align='center' class='TitleRow'><span class='midRed' style='color:#ffffff'><b>Current User Detail</b></span></td></tr>");

                    sbUserDetail.Append(@"<tr valign='top'>");
                    sbUserDetail.Append(@"<td>User Name</td>");
                    sbUserDetail.Append(@"<td>" + thisUser.userName + "</td>");
                    sbUserDetail.Append(@"</tr>");

                    sbUserDetail.Append(@"<tr valign='top'>");
                    sbUserDetail.Append(@"<td>Role</td>");
                    sbUserDetail.Append(@"<td>" + thisUser.role + "</td>");
                    sbUserDetail.Append(@"</tr>");

                    sbUserDetail.Append(@"<tr valign='top'>");
                    sbUserDetail.Append(@"<td># of votes</td>");
                    sbUserDetail.Append(@"<td>" + thisUser.Votes.Count() + "</td>");
                    sbUserDetail.Append(@"</tr>");

                    sbUserDetail.Append(@"<tr valign='top'>");
                    sbUserDetail.Append(@"<td>Most Recent Vote</td>");
                    sbUserDetail.Append(@"<td>" + gr.GetMostRecentVoteDateByUser(thisUser.userName).ToString() + "</td>");
                    sbUserDetail.Append(@"</tr>");

                    sbUserDetail.Append(@"</table>");
                    sbUserDetail.Append(@"</div>");

                    if (thisUser != null)
                    {
                        ViewData["UserDetail"] = sbUserDetail.ToString();

                    }
                    else
                    {
                        ViewData["UserDetail"] = "No User Found.";

                    }

                    var UserList = gr.GetUserLIst();



                    return View(UserList);
                }
                else
                {
                    return View();
                }                      

        }


        [AcceptVerbs(HttpVerbs.Get)]
        public ViewResult EditUser()
        {

            GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();
            GACFFP.User thisUser = new GACFFP.User();

            try
            {
                //get user by passing name into the onion username->userid->user
                thisUser = gr.GetCurrentUser();

                if (thisUser.role.Trim() != "admin")
                {
                    ViewData["PageMessage"] = @"You are not authorized to edit a user.<br />";

                    var UserList = gr.GetUserLIst();
                    return View("UserDetail", UserList);
                }

                GACFFP.User thisEditUser = new GACFFP.User();
                thisEditUser = gr.GetCurrentUser(Request.QueryString["u"], false);//and override setting the cookie by passing in false.

                List<GACFFP.Role> Roles = new List<GACFFP.Role>();
                Roles = gr.GetRolesList();
                ViewData["RolesList"] = Roles;

                return View(thisEditUser);

            }
            catch (Exception e)
            {
                //TODO logging logic


                ViewData["PageMessage"] = "Problem updating user.  :( <br />"+e.Message;
                var UserList = gr.GetUserLIst();
                return View("UserDetail", UserList);
            }



        }





        [AcceptVerbs(HttpVerbs.Post)]
        public ViewResult UpdateUser(FormCollection fc)
        {
            if (!ModelState.IsValid)
                return View();

            try
            {
                GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();


                String userName = fc["userName"].Trim();
                String userRole = fc["role"].Trim();

                GACFFP.User thisUser = gr.GetCurrentUser(userName, false);

                thisUser.role = userRole;
                thisUser.userName = userName;

                if (gr.UpdateUser(thisUser))
                {
                    ViewData["UpdateUserMessage"] = "Successfully updated - " + thisUser.userName;
                }
                else
                {
                    ViewData["UpdateUserMessage"] = "We were unable to update the user - " + thisUser.userName;
                }


            
            }
            catch (Exception e)
            { 
                //TODO Logging logic

                return View();
            }

            return View();
        }



        /// <summary>
        /// Fill the empty poll.
        /// </summary>
        /// <returns></returns>
        [AcceptVerbs(HttpVerbs.Get)]
        public ViewResult Vote()
        {
            GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();

            //first Check Voting Period.
            if (!Services.PeriodValidator.IsTodayInSeason())
            {
                ViewData["NoVoteMessage"] = "Today is outside of the season period for voting.";
                return View("NoVote");
            }
            if (!Services.PeriodValidator.IsTodayValid())
            {
                ViewData["NoVoteMessage"] = "Today is not an open vote day, please try again on a different day.";
                return View("NoVote");
            }


            //Get User
            GACFFP.User thisUser = gr.GetCurrentUser();

            //Second Check User if they can vote this period.
            if (thisUser == null)
            {
                ViewData["NoVoteMessage"] = "Not a valid user.";
                return View("NoVote");
            }

            

            ViewData["select_from"] = Generateselect_from();

            return View();
        }




        [AcceptVerbs(HttpVerbs.Post)]
        public ViewResult Vote(FormCollection fc)
        {




            if (!ModelState.IsValid)
                return View();

            try
            {
                //The assumption is that the select options arrive in order from first place to last.
                //otherwise this is all for naught.

                GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();

                //first Check Voting Period.
                if(!Services.PeriodValidator.IsTodayInSeason())
                {
                    ViewData["NoVoteMessage"] = "Today is outside of the season period for voting.";
                    return View("NoVote");
                }
                if (!Services.PeriodValidator.IsTodayValid())
                {
                    ViewData["NoVoteMessage"] = "Today is not an open vote day, please try again on a different day.";
                    return View("NoVote");
                }


                //Get User
                GACFFP.User thisUser = gr.GetCurrentUser();

                //Second Check User if they can vote this period.
                if (thisUser==null)
                {
                    ViewData["NoVoteMessage"] = "Not a valid user.";
                    return View("NoVote");
                }


               //Third Vote

                string selectedValues = fc["select_to"];
                string[] teams = selectedValues.Split(',');

                int thisTeamId;
                int curRank = 25;
                bool FirstPlace = true;


                List<GACFFP.Vote> CurrentVotes = new List<GACFFP.Vote>();

                if (thisUser.id > 0)
                {
                    foreach (var option in teams)
                    {

                        thisTeamId = Convert.ToInt32(option);

                        GACFFP.Vote thisVote = new GACFFP.Vote();

                        thisVote.teamID = thisTeamId;
                        thisVote.Points = curRank;
                        thisVote.UserID = thisUser.id;
                        thisVote.Date = DateTime.Now;
                        if (FirstPlace)
                        {
                            thisVote.FirstPlaceVotes = 1;
                            FirstPlace = false;
                        }

                        thisVote.VoteSourceID = Services.IdentifySource.GetVoteSource();

                        CurrentVotes.Add(thisVote);

                        if (curRank > 1)
                        {
                            curRank--;
                        }
                        else
                        {
                            break;
                        }
                    }

                    gr.AddVote(CurrentVotes);


                    return View("VoteResult");

                }
                else 
                {
                    return View("NoVote");
                }
            }
            catch (Exception ex)
            {

                return View(ex.Message);
            }

        }



        public ViewResult SeasonPeriod()
        {

            GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();

            DateTime StartOfSeason = gr.GetStartOfSeason(1);
            DateTime EndOfSeason = gr.GetEndOfSeason(1);

            string[] AllowedDaysToVote = gr.GetAllowedDaysToVote();

            ViewData["SeasonStart"] = StartOfSeason.ToString();
            ViewData["SeasonEnd"] = EndOfSeason.ToString();
            ViewData["AllowedDaysToVote"] = AllowedDaysToVote;

            return View();
        
        }


        //public ViewResult CreateSeason()
        //{
        //    GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();



        //    ViewData["SeasonIsCreated"] = gr.UpdateStartOfSeason();


        //    DateTime StartOfSeason = gr.GetStartOfSeason(1);
        //    DateTime EndOfSeason = gr.GetEndOfSeason(1);

        //    ViewData["SeasonStart"] = StartOfSeason.ToString();
        //    ViewData["SeasonEnd"] = EndOfSeason.ToString();


        //    return View();
        //}


        [AcceptVerbs(HttpVerbs.Post)]
        public ViewResult UpdateSeason(FormCollection fc)
        {
            GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();

            String start = fc["SeasonStart"];
            String end = fc["SeasonEnd"];

            ViewData["sentStartDate"] = start;
            ViewData["sentEndDate"] = end;
            
            //parse date - 10/18/2011 
            //note the datetime class wants it in year month day.
            //therefore we pass it in 2,0,1 as indexed in the array
            string[] parsedStartDate = start.Split('/');
            DateTime newStart = new DateTime(Int32.Parse(parsedStartDate[2]), Int32.Parse(parsedStartDate[0]), Int32.Parse(parsedStartDate[1]));
            ViewData["SeasonIsUpdated"] = gr.UpdateStartOfSeason(newStart);


            string[] parsedEndDate = end.Split('/');
            DateTime newEnd = new DateTime(Int32.Parse(parsedEndDate[2]), Int32.Parse(parsedEndDate[0]), Int32.Parse(parsedEndDate[1]));
            ViewData["SeasonIsUpdated"] = gr.UpdateEndOfSeason(newEnd);

            DateTime StartOfSeason = gr.GetStartOfSeason(1);
            DateTime EndOfSeason = gr.GetEndOfSeason(1);

            ViewData["SeasonStart"] = StartOfSeason.ToString();
            ViewData["SeasonEnd"] = EndOfSeason.ToString();


            return View();
        }







        ///helper functions/////
        ///
        /// 
      
        /// <summary>
        /// Get the list of teams back.
        /// </summary>
        /// <returns></returns>
        private static List<SelectListItem> Generateselect_from()
        {
            GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();

            var teams = gr.FindAllTeams();

            IList<SelectListItem> select_from = new List<SelectListItem>();

            foreach (var team in teams)
            {
                SelectListItem select = new SelectListItem();
                select.Text = team.teamName;
                select.Value = team.id.ToString();
                select_from.Add(select);
            }


            return select_from.ToList();
        }


        /// <summary>
        /// Checks all the validation routines and returns one boolean
        /// </summary>
        /// <returns></returns>
        private static bool IsItOKToVote()
        {
          
            GACFFP.Models.GACFFP_Repository gr = new Models.GACFFP_Repository();

            bool OkToVote = GACFFP.Services.PeriodValidator.IsTodayInSeason() &&
                            GACFFP.Services.PeriodValidator.IsTodayValid() &&
                            GACFFP.Services.ValidateVoter.IsValidVoter(gr.GetCurrentUser().userName);

            

            return OkToVote;
        }



    }
}
